容器
我们可以将字符堆栈类型推广到一个任意类型的堆栈的类型,方法是将它做成一个模板(template
),用一个模板参数取代特定的类型 char
。例如,
template<class T> class Stack
{
T* v;
int max_size;
int top;
public:
class Underflow { };
class Overflow { };
Stack(int s); // 构造函数
~Stack(); // 析构函数
void push(T);
T pop();
};
前缀 template <class T>
说明在以此作为前缀的声明中,T
将被看做是一个参数。
成员函数可以类似地定义为:
template<class T> void Stack<T>::push(T c)
{
if(top == max_size) throw Overflow();
v[top] = c;
top = top + 1;
}
template<class T> T Stack<T>::pop()
{
if(top == 0) throw Underflow();
top = top - 1;
return v[top];
}
有了这些定义之后,我们就可以按
Stack<char> sc(200); // 200个字符的堆栈
Stack<complex> scplx(30); // 30个复数的堆栈
Stack<list<int>> sli(45); // 45个整数表的堆栈
void f()
{
sc.push('c');
if(sc.pop() != 'c') throw Bad_pop();
scplx.push(complex(1.2));
if(scplx.pop() != complex(1.2)) throw Bad_pop();
}
方式使用堆栈了。类似地,我们也能将表、向量、映射(也就是关联数组)等都定义为模板。一个能保存某种类型的一集元素的类,一般被称为一个容器类,或简单地称做容器。
模板是一种编译时的机制,因此,与“手工编写的代码”相比,它们的使用并不引起任何额外的运行时开销。
🔚